using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[Serializable]
public class SoundData
{
    public string key;
    public AudioClip clip;
    [Range(0f, 1f)] public float volume = 1f;
    public bool loop = false;
    [Tooltip("Priority for SFX (lower = higher priority)")] public int priority = 128;
}
public class AudioSystem : MonoBehaviour
{

    [Header("Audio Sources")]
    public AudioSource musicSource; // 背景音乐主源
    public AudioSource musicSource2; // 切换淡入淡出备用源（可选）
    public AudioSource sfxSourcePrefab; // 若需对象池可用 prefab
    public Transform sfxParent;

    [Header("Sounds")]
    public List<SoundData> musicList = new List<SoundData>();
    public List<SoundData> sfxList = new List<SoundData>();

    [Header("Settings")]
    [Range(0f, 1f)] public float masterVolume = 1f;
    [Range(0f, 1f)] public float musicVolume = 1f;
    [Range(0f, 1f)] public float sfxVolume = 1f;
    public bool dontDestroyOnLoad = true;

    private Dictionary<string, SoundData> musicMap = new Dictionary<string, SoundData>();
    private Dictionary<string, SoundData> sfxMap = new Dictionary<string, SoundData>();

    private void Awake()
    {
        if (dontDestroyOnLoad) DontDestroyOnLoad(gameObject);

        // 若未在 Inspector 指定 AudioSource，则创建默认的
        if (musicSource == null)
        {
            musicSource = gameObject.AddComponent<AudioSource>();
            musicSource.playOnAwake = false;
            musicSource.loop = true;
        }
        if (musicSource2 == null)
        {
            GameObject go = new GameObject("MusicSource2");
            go.transform.SetParent(transform);
            musicSource2 = go.AddComponent<AudioSource>();
            musicSource2.playOnAwake = false;
            musicSource2.loop = true;
        }
        if (sfxParent == null) sfxParent = transform;

        // Build maps
        foreach (var s in musicList) if (!string.IsNullOrEmpty(s.key) && s.clip != null) musicMap[s.key] = s;
        foreach (var s in sfxList) if (!string.IsNullOrEmpty(s.key) && s.clip != null) sfxMap[s.key] = s;
    }

    private void Start()
    {
        ApplyVolumes();
    }

    #region Volume Controls
    public void SetMasterVolume(float v)
    {
        masterVolume = Mathf.Clamp01(v);
        ApplyVolumes();
    }
    public void SetMusicVolume(float v)
    {
        musicVolume = Mathf.Clamp01(v);
        ApplyVolumes();
    }
    public void SetSFXVolume(float v)
    {
        sfxVolume = Mathf.Clamp01(v);
        ApplyVolumes();
    }
    private void ApplyVolumes()
    {
        musicSource.volume = masterVolume * musicVolume;
        musicSource2.volume = masterVolume * musicVolume;
    }
    #endregion

    #region Music Playback
    // 立即播放背景音乐（替换当前）
    public void PlayMusic(string key, bool loop = true)
    {
        if (!musicMap.ContainsKey(key)) { Debug.LogWarning($"Music key not found: {key}"); return; }
        var s = musicMap[key];
        musicSource.clip = s.clip;
        musicSource.loop = loop && s.loop;
        musicSource.volume = masterVolume * musicVolume * s.volume;
        musicSource.Play();
    }

    // 淡入切换音乐（crossfade）
    public void CrossFadeMusic(string key, float duration = 1f)
    {
        if (!musicMap.ContainsKey(key)) { Debug.LogWarning($"Music key not found: {key}"); return; }
        var s = musicMap[key];
        StartCoroutine(CrossFadeCoroutine(s.clip, duration, s.volume, s.loop));
    }

    private IEnumerator CrossFadeCoroutine(AudioClip newClip, float duration, float clipVolume, bool loop)
    {
        // 准备备用 source
        musicSource2.clip = newClip;
        musicSource2.loop = loop;
        musicSource2.volume = 0f;
        musicSource2.Play();

        float t = 0f;
        float fromVol = musicSource.volume;
        float targetVol = masterVolume * musicVolume * clipVolume;

        while (t < duration)
        {
            t += Time.deltaTime;
            float k = Mathf.Clamp01(t / duration);
            musicSource.volume = Mathf.Lerp(fromVol, 0f, k);
            musicSource2.volume = Mathf.Lerp(0f, targetVol, k);
            yield return null;
        }

        // 完成
        musicSource.Stop();
        musicSource.clip = musicSource2.clip;
        musicSource.volume = targetVol;
        musicSource.loop = loop;
        musicSource.Play();

        musicSource2.Stop();
        musicSource2.clip = null;
        musicSource2.volume = 0f;
    }

    public void StopMusic()
    {
        musicSource.Stop();
        musicSource2.Stop();
    }

    public void PauseMusic()
    {
        musicSource.Pause();
        musicSource2.Pause();
    }
    public void UnPauseMusic()
    {
        musicSource.UnPause();
        musicSource2.UnPause();
    }
    #endregion

    #region SFX Playback
    // 简单 OneShot 播放（不池化）
    public void PlaySFX(string key, float volumeScale = 1f)
    {
        if (!sfxMap.ContainsKey(key)) { Debug.LogWarning($"SFX key not found: {key}"); return; }
        var s = sfxMap[key];
        float vol = Mathf.Clamp01(masterVolume * sfxVolume * s.volume * volumeScale);
        sfxSourcePrefab.PlayOneShot(s.clip, vol);
    }

    // 或创建临时 AudioSource 来播放（便于不同位置的音效）
    public AudioSource PlaySFXAt(string key, Vector3 worldPos, float volumeScale = 1f, float spatialBlend = 1f)
    {
        if (!sfxMap.ContainsKey(key)) { Debug.LogWarning($"SFX key not found: {key}"); return null; }
        var s = sfxMap[key];
        GameObject go = new GameObject($"sfx_{key}");
        go.transform.SetParent(sfxParent);
        go.transform.position = worldPos;
        AudioSource a = go.AddComponent<AudioSource>();
        a.clip = s.clip;
        // a.spatialBlend = spatialBlend;
        a.volume = Mathf.Clamp01(masterVolume * sfxVolume * s.volume * volumeScale);
        //a.priority = s.priority;
        a.Play();
        Destroy(go, s.clip.length + 0.1f);
        return a;
    }
    #endregion

    #region Helpers
    public bool HasMusic(string key) => musicMap.ContainsKey(key);
    public bool HasSFX(string key) => sfxMap.ContainsKey(key);
    #endregion
}
